#include <windows.h>
#include "Game.h"
#include <stdlib.h>
#include <ctime>

#define _CRTDBG_MAP_ALLOC
#include <cstdlib>
#include <crtdbg.h>
#define LEAK_LINE -1L

long			g_ScreenWidth	=	800;
long			g_ScreenHeight	=	600;
const char		g_GameClass[32]	=	"Project MuttonChops";
const char		g_GameTitle[32]	=	"Project MuttonChops";
DWORD			g_WindowStyle	=	0;

bool InitWindow( HINSTANCE app, HWND &wnd );	// Inits window

int WINAPI WinMain(HINSTANCE hInstance,		// handle to application
				   HINSTANCE hPrevInstance,	// handle to previous app
				   LPTSTR lpCmdLine,		// command line string
				   int nCmdShow );			// show window value

LRESULT CALLBACK WndProc(HWND hWnd,			// handle to window
						 UINT message,		// incoming message
						 WPARAM wparam,		// message info
						 LPARAM lparam );	// message info

bool InitWindow( HINSTANCE app, HWND &wnd )
{   
    WNDCLASSEX  wndClass;

	// register a new type of window
	ZeroMemory( &wndClass, sizeof( wndClass ) );
	wndClass.cbSize         = sizeof( WNDCLASSEX );             // size of window structure
	wndClass.lpfnWndProc    = ( WNDPROC )WndProc;               // message callback
	wndClass.lpszClassName  = g_GameClass;						// class name
	wndClass.hInstance      = app;								// handle to application
	wndClass.hCursor        = LoadCursor( NULL, IDC_ARROW );    // default cursor
	wndClass.hbrBackground  = ( HBRUSH )( COLOR_WINDOWFRAME );  // background brush
	RegisterClassEx( &wndClass );

	g_WindowStyle |= WS_OVERLAPPEDWINDOW;

	// create window of registered type
	wnd = CreateWindowEx(
		WS_EX_APPWINDOW,										// extended class style
	    g_GameClass, g_GameTitle,								// class name, window title 
		g_WindowStyle,											// window style
	    CW_USEDEFAULT, CW_USEDEFAULT,           			    // x & y coordinates
	    g_ScreenWidth, g_ScreenHeight,            			    // width & height of window
	    NULL, NULL,                             			    // parent window & menu
	    app,													// handle to application
	    NULL );

    ShowWindow( wnd, SW_SHOW );									// technically should be nCmdShow
    return true;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
	_CrtSetBreakAlloc(LEAK_LINE);

	HINSTANCE app;
	HWND wnd = NULL;

    app = hInstance;
    InitWindow( app, wnd );
	
    MSG msg; 
	ZeroMemory( &msg, sizeof( msg ) );
  
	// Initialize the game
	Game *gameManager = Game::GetInstance();
	gameManager->Initialize(wnd, app, g_ScreenWidth, g_ScreenHeight, true, true);

	while( gameManager->GameRunning() ) 
    {
		// Handle input
		gameManager->Input();
		
		if( !gameManager->GameRunning() )
			break;
		// Update the game
		gameManager->Update();

		// Render
		gameManager->Render();

		// Exit the game
		if( msg.message == WM_QUIT )
			break;

        if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {  
			TranslateMessage( &msg ); 
			DispatchMessage( &msg ); 
		}
    }

	// Shutdown the game
	gameManager->Shutdown();
	
	//_CrtDumpMemoryLeaks();
	UnregisterClass( "Prj MC", app );
    return 0;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    // attempt to handle
    switch ( message )
    {
        case ( WM_DESTROY ):
			{ 
				PostQuitMessage( 0 ); 
			}
        break;
    }
    // pass to default handler
    return DefWindowProc( hWnd, message, wParam, lParam );
}